
$Id:$

package Enclosure;

use strict;
use 5.008000;
use warnings;
use Scalar::Util;
use List::Util 'first';
use Carp;

use Net::Telnet;
use XML::Twig;
use Data::Dumper;

use Volume;
use Vdisk;

my %host;
my %name;
my %ip;
my %vdisks;
my %errorstr;

sub new {
    my ($proto, $args_ref) = @_;

    my $class = ref($proto) || $proto;
    my $self = bless \do{my $anon}, $class;

    my $ident = refaddr $self;

    $host{$ident}     = undef;
    $name{$ident}     = $args_ref->{name};
    $ip{$ident}       = $args_ref->{ip};
    $vdisks{$ident}   = [];
    $errorstr{$ident} = '';

    return $self;
}

sub DESTROY {
    my $self = shift;

    my $ident = refaddr $self;
    delete $host{$ident};
    delete $name{$ident};
    delete $ip{$ident};
    delete $vdisks{$ident};
    delete $errorstr{$ident};
}

#=============================================
# set/get accessors
sub set_host {
    my ($self, $host) = @_;
    $host{refaddr $self} = $host;

    return;
}

sub get_host {
    my $self = shift;

    return $host{refaddr $self};
}

sub get_name {
    my $self = shift;

    return $name{refaddr $self};
}

sub get_ip {
    my $self = shift;

    return $ip{refaddr $self};
}

sub get_vdisks {
    my $self = shift;

    return $vdisks{refaddr $self};
}

sub set_error {
    my ($self, $errorstr) = @_;
    $errorstr{refaddr $self} = $errorstr;

    return;
}

sub get_error {
    my $self = shift;

    return $errorstr{refaddr $self};
}

#==========================================
# utilities
sub find_vdisk_by_name {
    my ($self, $vdname) = @_;

    my $vdisks = $self->get_vdisks();
    return first { $_->get_name() eq $vdname } @{ $vdisks };
}

sub add_vdisk {
    my ($self, $vdisk) = @_;

    push @{ $vdisks{ refaddr $self } }, $vdisk;

    return;
}

sub add_volumes {
    my ($self, $vdname, @volumes) = @_;

    my $vdisk = $self->find_vdisk_by_name($vdname);

    if ($vdisk) {
        $vdisk->add_volume(@volumes);
    }

    return;
}

sub delete_vdisk_by_name {
    my ($self, $vdname) = @_;

    my @vdisks = grep { $_->get_name() ne $vdname}
                      @{ $vdisks{ refaddr $self } };

    $vdisks{ refaddr $self } = \@vdisks;
    return;
}

sub delete_volumes_by_name {
    my ($self, $vdname, @volnames) = @_;
    my $vdisk = $self->find_vdisk_by_name($vdname);

    if ($vdisk) {
        $vdisk->delete_volumes_by_name(@volnames);
    }
    return;
}


sub to_string {
    my $self = shift;

    my $str.
    for my $vdisk (sort @{ $vdisks{ refaddr $self } }) {
        $str .= $vdisk->to_string() . "\n";
    }

    return $str;
}

1;

